

#include "DropMgr.h"

#include "../newAI/behaviac/CreatureCommonAI.h"
#include "base/core/log.h"
#include "base/core/random.h"
#include "Common/TableData/MonsterMonsterCfg.h"
#include "Character/PlayerMgr.h"
#include "Duplicate/DuplicateMgr.h"
#include "Common/TableData/BoxDropCfg.h"
#include "Character/CreatureMgr.h"
#include "Common/TableDataEx/DropCfg.h"
#include "ServerModule/LogicActivityModule.h"
#include "Common/TableData/EquipEquipCfg.h"
#include "Team/GTeamManager.h"
#include "Mission/MissionManager.h"
#include "Common/TableDataEx/PkModeCfg.h"
#include "Chat/ChatManager.h"
#include "Common/TableData/ConstantConstantCfg.h"
#include "Common/TableData/ReduceReduceCfg.h"
#include "Common/TableDataEx/ReduceCfg.h"
#include "base/core/utility.h"
#include "Character/welfare/OperateWelfareMgr.h"
#include "Common/TableDataEx/MapCfg.h"
#include "Common/TableDataEx/DuplicateCfg.h"

DropMgr::DropMgr()
{
}

DropMgr::~DropMgr()
{
}

bool DropMgr::Init()
{
	g_GetEvent()->Subscribe(this, EVENT_CREATURE_DEAD, 0, CREATURE_MONSTER, "DropMgr");
	//g_GetEvent()->Subscribe(this, EVENT_CREATURE_DEAD, 0, CREATURE_PLAYER, "DropMgr");

	/* 测试代码	
	uint32_t nBoxID = 390135013;
	VEC_ITEM_PROTO_EX vecProtoEx;
	int32_t goldNum = 0;
	int32_t diamondNum = 0;
	int32_t bindDiamond = 0;
	BoxCondCfg boxCond;
	LIST_UINT32 lstGrid;
	LIST_ITEM lstItem;
	g_GetItemMgr()->ZhuanPanDropItem(nBoxID, lstGrid, lstItem,1);
	*/


	return true;
}

bool DropMgr::UnInit()
{
	g_GetEvent()->UnSubscribeAll(this);
	g_GetTimerAxis()->KillAllTimer(this);
	g_GetTimerAxis()->KillAllFixTimer(this);

	return true;
}

bool DropMgr::Update(uint64_t tick)
{
	return true;
}

void DropMgr::OnTimer(uint32_t nTimerID)
{
	switch (nTimerID)
	{
	case 1:
		break;
	}
}

void DropMgr::OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen)
{
	switch (nEventID)
	{
	case EVENT_CREATURE_DEAD:
		{
			BEGIN_PROFILE("DropMgr::OnExecute");
			if ((uint32_t)nLen >= sizeof(DieEvent))
			{
				DieEvent *pDieEvent = (DieEvent*)pContext;
				if (CREATURE_MONSTER == bySrcType)
				{
					OnMonsterDieDrop(pDieEvent);
				}
				/*else if (CREATURE_PLAYER == bySrcType)
				{
					OnPlayerDieDrop(pDieEvent);
				}*/
			}
			END_PROFILE();
		}
		break;
	default:
		break;
	}
}

bool DropMgr::CreateDrop(VEC_ITEM_PROTO_EX &vecProtoEx, VEC_UINT32 &vecGold, Scene *pScene, Point3<float> &midPos, int8_t byDropType, SET_UINT64 &setTypeVal, int32_t dropInitProtect, SDropSourcePram &source)
{
	if (nullptr == pScene)
	{
		return false;
	}
	//这里需要先根据midPos在中点坐标周围随机一些规则排列的坐标出来
	//暂时掉落坐标生成函数没有，暂时全部掉在一个坐标点上
	uint32_t nSceneID = pScene->GetSceneId();
	int32_t count = (int32_t)(vecProtoEx.size() + vecGold.size());
	VecPoint3 vecPoint3;
	vecPoint3.clear();
	pScene->FindPointLstInRect(midPos, vecPoint3, 2.0f, 2.0f, count);
	if ((int32_t)vecPoint3.size() < count)
	{
		MMOLOG_FMT_ERROR("DropMgr::CreateDrop...vecPoint3.size() < count....sceneid:%u, mapid:%u, count:%d,size:%d, midpos:%f,%f,%f,droptype:%d,",pScene->GetSceneId(),pScene->GetMapId(),count,vecPoint3.size(),midPos.x,midPos.y,midPos.z,byDropType)
	}

	VEC_ITEM_PROTO_EX::iterator iter = vecProtoEx.begin();
	while (iter != vecProtoEx.end())
	{
		ItemProtoInfo &proto = (*iter);
		//判断下是否还有掉落坐标，如果没有了直接退出
		if (vecPoint3.size() <= 0)
		{
			break;
		}
		VecPoint3::iterator iterPoint = vecPoint3.begin();
		Point3<float> bornPos = (*iterPoint);

		CItemBase *pItem = nullptr;
		VEC_ITEM_PROTO_EX vecProtoDrop;
		vecProtoDrop.clear();
		VEC_PACKAGE_ITEM vecDropItems;
		vecDropItems.clear();
		//
		vecProtoDrop.push_back(proto);
		if (g_GetItemMgr()->CreateItem(vecProtoDrop,vecDropItems))
		{
			if (vecDropItems.size() > 0)
			{
				pItem = (*vecDropItems.begin());
			}
		}
		if (nullptr == pItem)
		{
			++iter;
			continue;
		}

		if (!g_GetCreatureMgr()->CreateDropEx(pItem, 0, nSceneID, bornPos, byDropType, setTypeVal,dropInitProtect,source))
		{
			LogErrFmtPrint("[logic] create drop failed, sceneId:%u bornPos:%f,%f,%f", nSceneID, bornPos.x, bornPos.y, bornPos.z);
			//创建掉落失败，回收物品，这里回收了，在 g_GetCreatureMgr()->CreateDrop 里面就不要重复回收了
			g_GetItemMgr()->FreeItemObj(pItem);
			++iter;
			continue;
		}
		vecPoint3.erase(iterPoint);
		iter = vecProtoEx.erase(iter);
	}

	VEC_UINT32::iterator iterGold = vecGold.begin();
	while (iterGold != vecGold.end())
	{
		uint32_t igold = (*iterGold);
		if (0 == igold)
		{
			iterGold = vecGold.erase(iterGold);
			continue;
		}
		//判断下是否还有掉落坐标，如果没有了直接退出
		if (vecPoint3.size() <= 0)
		{
			break;
		}
		VecPoint3::iterator iterPoint = vecPoint3.begin();
		Point3<float> bornPos = (*iterPoint);
		if (!g_GetCreatureMgr()->CreateDropEx(nullptr, igold, nSceneID, bornPos, byDropType, setTypeVal, dropInitProtect, source))
		{
			LogErrFmtPrint("create drop failed 11, sceneId:%d , gold:%u,  bornPos:%f,%f,%f", nSceneID, igold, bornPos.x, bornPos.y, bornPos.z);

			++iterGold;
			continue;
		}
		//
		vecPoint3.erase(iterPoint);
		iterGold = vecGold.erase(iterGold);
	}

	return true;
}
//创建掉落
bool DropMgr::CreateDrop(uint32_t nDropID, uint32_t nSceneID, Point3<float> &midPos, int8_t byDropType, SET_UINT64 &setTypeVal, uint32_t monsId, int32_t monsLev, int32_t dropInitProtect,SDropSourcePram &source)
{
	Scene *pScene = g_GetSceneMgr()->GetScene(nSceneID);
	if (nullptr == pScene)
	{
		return false;
	}
	return CreateDrop(nDropID, pScene, midPos, byDropType, setTypeVal, monsId, monsLev, dropInitProtect,source);
}
//创建掉落
bool DropMgr::CreateDrop(uint32_t nDropID, Scene *pScene, Point3<float> &midPos, int8_t byDropType, SET_UINT64 &setTypeVal, uint32_t monsId, int32_t monsLev, int32_t dropInitProtect, SDropSourcePram &source, int32_t itemReduce /*= DROP_RAND_BASE_NUM*/, int32_t goldReduce /*= DROP_RAND_BASE_NUM*/)
{
	VEC_ITEM_PROTO_EX vecProtoEx;
	vecProtoEx.clear();
	VEC_UINT32 vecGold;
	vecGold.clear();
	SItemCond itemCond;//掉落物品不知道物品条件，这里取默认值
	if (nDropID > 0)
	{
		if (!g_GetItemMgr()->CreateDropItem(nDropID, vecProtoEx, vecGold, itemCond, itemReduce, goldReduce))
		{
			return false;
		}
	}
	//检查动态怪掉落
	OnDyMonsDrop(monsId, monsLev, vecProtoEx, vecGold, itemCond, goldReduce, itemReduce);
	//检查活动期间怪物掉落
	OnMonsDropDuringAct(monsId, vecProtoEx, vecGold, goldReduce, itemReduce);
	//
	return CreateDrop(vecProtoEx, vecGold, pScene, midPos, byDropType, setTypeVal, dropInitProtect, source);
}


//玩家独立掉落
bool DropMgr::AddDrop(Creature *pCreature, Point3<float>&pos, uint32_t nDropID, uint32_t monsId, int32_t monsLev, SDropSourcePram &source)
{
	if (nullptr == pCreature)
	{
		return false;
	}
	uint32_t sceneId = pCreature->GetSceneId();
	Scene *pScene = g_GetSceneMgr()->GetScene(sceneId);
	if (nullptr == pScene)
	{
		return false;
	}
	SET_UINT64 setTypeVal;
	setTypeVal.clear();
	setTypeVal.insert(pCreature->GetCid());
	int32_t openReduce = 0;
	int32_t dropInitProtect = 0;
	GetMonsDropParam(monsId, openReduce, dropInitProtect);
	return AddDrop(pCreature, pScene, nDropID, pos, (int8_t)EDropType::EDropType_Independence, setTypeVal, monsId, monsLev, dropInitProtect, openReduce, source);
}

//添加野外掉落
bool DropMgr::AddWildDrop(Creature *pCreature, uint32_t sceneId, Point3<float>&pos, int32_t monsDropType, uint32_t dropId, uint32_t monsId, int32_t monsLev, SDropSourcePram &source)
{
	Scene *pScene = g_GetSceneMgr()->GetScene(sceneId);
	if (nullptr == pScene)
	{
		return false;
	}
	return AddNormalDrop(pCreature, pScene, dropId, monsDropType, pos, monsId, monsLev, source);
}

//添加工会掉落
bool DropMgr::AddUnionDrop(uint32_t sceneId, Point3<float>&pos, uint32_t dropId, SET_UINT32 &setUnion, SDropSourcePram &source)
{
	if (setUnion.size() < 1)
	{
		return false;
	}
	Scene *pScene = g_GetSceneMgr()->GetScene(sceneId);
	if (nullptr == pScene)
	{
		return false;
	}
	VEC_ITEM_PROTO_EX vecProtoEX;
	vecProtoEX.clear();
	VEC_UINT32 vecGold;
	vecGold.clear();
	SItemCond itemCond;//工会掉落无法知道物品条件
	if (!g_GetItemMgr()->CreateDropItem(dropId, vecProtoEX, vecGold, itemCond))
	{
		return false;
	}
	if (vecProtoEX.size() <= 0)
	{
		return false;
	}
	VEC_ITEM_PROTO_EX vecDropProtoEx;
	vecDropProtoEx.clear();
	vecDropProtoEx.push_back(vecProtoEX.at(0));
	VEC_PACKAGE_ITEM vecDropItem;
	vecDropItem.clear();
	if (!g_GetItemMgr()->CreateItem(vecDropProtoEx, vecDropItem))
	{
		return false;
	}
	if (vecDropItem.size() <= 0)
	{
		return false;
	}
	SET_UINT64 setTypeVal;
	setTypeVal.clear();
	SET_UINT32::iterator iterUnion = setUnion.begin();
	for (; iterUnion != setUnion.end(); ++iterUnion)
	{
		uint64_t unionId = (*iterUnion);
		setTypeVal.insert(unionId);
	}

	bool bResult = false;
	CItemBase *pItem = (*vecDropItem.begin());
	Drop *pDrop = g_GetCreatureMgr()->CreateDropEx(pItem, 0, sceneId, pos, (int8_t)EDropType::EDropType_Union, setTypeVal,DROP_INIT_PROTECT_TIME,source);
	if (nullptr != pDrop)
	{
		bResult = true;
		vecDropItem.erase(vecDropItem.begin());
	}
	//回收剩余的物品
	VEC_PACKAGE_ITEM::iterator iterDel = vecDropItem.begin();
	for (; iterDel != vecDropItem.end(); ++iterDel)
	{
		g_GetItemMgr()->FreeItemObj((*iterDel));
	}

	return bResult;
}

//添加工会掉落，通过玩家背包指定物品类型
bool DropMgr::AddUnionDropByPlayer(uint32_t sceneId, Point3<float>&pos, CharIDType charId, int32_t itemSubType, SET_UINT32 &setUnion, SDropSourcePram &source)
{
	Player *pPlayer = g_GetSceneMgr()->GetPlayer(sceneId, charId);
	if (nullptr == pPlayer)
	{
		return false;
	}
	Part *pPackagePart = pPlayer->GetPart(PART_PACKAGE);
	if (nullptr == pPackagePart)
	{
		return false;
	}
	const CItemBase *pItem = pPackagePart->GetItemByType(itemSubType);
	if (nullptr == pItem)
	{
		return false;
	}
	VEC_COMMON_ITEM vecPackageItem;
	vecPackageItem.clear();
	vecPackageItem.push_back(pItem);


	SET_UINT64 setTypeVal;
	setTypeVal.clear();
	SET_UINT32::iterator iterUnion = setUnion.begin();
	for (; iterUnion != setUnion.end(); ++iterUnion)
	{
		uint64_t unionId = (*iterUnion);
		setTypeVal.insert(unionId);
	}
	
	SET_Drop setDrop;
	setDrop.clear();
	MAP_UINT16_INT32 mapIdxNum;
	mapIdxNum.clear();
	PackageDrop(pPlayer, pos, vecPackageItem, setDrop, mapIdxNum, (int8_t)EDropType::EDropType_Union, setTypeVal,source,pPlayer->GetCid());
	if (setDrop.size() > 0)
	{
		//掉落成功，才移除玩家背包物品，避免掉落不成功，玩家背包物品又被移除了
		SItemSourceParam sourceParam;
		sourceParam.source = S_UnionDrop;
		pPackagePart->RemoveAllByType(itemSubType, sourceParam);
		return true;
	}
	return false;
}

//普通场景掉落 (副本之外的)
bool DropMgr::AddNormalDrop(Creature *pCreature, Scene *pScene, uint32_t nDropID, int32_t monsDropType, Point3<float> &midPos, uint32_t monsId, int32_t monsLev, SDropSourcePram &source, int32_t itemReduce /*= DROP_RAND_BASE_NUM*/, int32_t goldReduce /*= DROP_RAND_BASE_NUM*/)
{
	if (nullptr == pScene)
	{
		return false;
	}
	int32_t openReduce = 0;
	int32_t dropInitProtect = 0;
	GetMonsDropParam(monsId, openReduce, dropInitProtect);
	
	SET_UINT64 setTypeVal;
	setTypeVal.clear();
	Player *pPlayer = dynamic_cast<Player*>(pCreature);
	if (nullptr == pPlayer) //没有掉落归属，是公共掉落
	{
		return AddDrop(pCreature, pScene, nDropID, midPos, (int8_t)EDropType::EDropType_Public, setTypeVal, monsId, monsLev, dropInitProtect, openReduce, source, itemReduce, goldReduce);
	}
	if (EMonsterDropType_Default == monsDropType)
	{
		uint32_t teamId = pPlayer->GetAttr(C_TEAM_ID);
		if (teamId > 0) //有组队，队伍掉落
		{
			setTypeVal.insert((uint64_t)teamId);
			return AddDrop(pCreature, pScene, nDropID, midPos, (int8_t)EDropType::EDropType_Team, setTypeVal, monsId, monsLev, dropInitProtect, openReduce, source, itemReduce, goldReduce);
		}
		//没有组队，属于个人掉落
		setTypeVal.insert(pPlayer->GetCid());
		return AddDrop(pCreature, pScene, nDropID, midPos, (int8_t)EDropType::EDropType_Personal, setTypeVal, monsId, monsLev, dropInitProtect, openReduce, source, itemReduce, goldReduce);
	}
	else if (EMonsterDropType_Camp == monsDropType)
	{
		setTypeVal.insert((uint64_t)pPlayer->GetCampId());
		return AddDrop(pCreature, pScene, nDropID, midPos, (int8_t)EDropType::EDropType_Camp, setTypeVal, monsId, monsLev, dropInitProtect, openReduce, source, itemReduce, goldReduce);
	}
	else if (EMonsterDropType_Union == monsDropType)
	{
		/*
		 公会掉落指的是：掉落的的道具只有掉落归属权拥有者以及与他同公会的玩家均可拾取。掉落的道具屏幕内是所有玩家都可以看到。
		 若玩家无公会，则掉落的道具归玩家个人拾取，走个人掉落。
		*/
		if (pPlayer->GetAttr(C_UNION_ID) <= 0)
		{
			uint32_t teamId = pPlayer->GetAttr(C_TEAM_ID);
			if (teamId > 0) //有组队，队伍掉落
			{
				setTypeVal.insert((uint64_t)teamId);
				return AddDrop(pCreature, pScene, nDropID, midPos, (int8_t)EDropType::EDropType_Team, setTypeVal, monsId, monsLev, dropInitProtect, openReduce, source, itemReduce, goldReduce);
			}
			//没有组队，属于个人掉落
			setTypeVal.insert(pPlayer->GetCid());
			return AddDrop(pCreature, pScene, nDropID, midPos, (int8_t)EDropType::EDropType_Personal, setTypeVal, monsId, monsLev, dropInitProtect, openReduce, source, itemReduce, goldReduce);
		}
		else
		{
			setTypeVal.insert((uint64_t)pPlayer->GetAttr(C_UNION_ID));
			return AddDrop(pCreature, pScene, nDropID, midPos, (int8_t)EDropType::EDropType_Union, setTypeVal, monsId, monsLev, dropInitProtect, openReduce, source, itemReduce, goldReduce);
		}
		
	}
	return false;
}

//添加掉落
bool DropMgr::AddDrop(Creature *pCreature, Scene *pScene, uint32_t nDropID, Point3<float> &midPos, int8_t byDropType, SET_UINT64 &setTypeVal, uint32_t monsId, int32_t monsLev, int32_t dropInitProtect, int32_t openReduce, SDropSourcePram &source, int32_t itemReduce /*= DROP_RAND_BASE_NUM*/, int32_t goldReduce /*= DROP_RAND_BASE_NUM*/)
{
	if (nullptr != pCreature)
	{
		if (CREATURE_PLAYER != pCreature->CreatureKind())
		{
			return false;
		}		
	}
	else
	{
		if ((int8_t)EDropType::EDropType_Public != byDropType) //公共掉落 pCreature 才允许为空
		{
			return false;
		}
	}
	if (nullptr == pScene)
	{
		return false;
	}
	if (byDropType <= (int8_t)EDropType::EDropType_none || byDropType >= (int8_t)EDropType::EDropType_limit )
	{
		return false;
	}
	int32_t itemReduceEx = itemReduce;
	int32_t goldReduceEx = goldReduce;
	if (!openReduce)
	{
		//未开启等级衰减,等级衰减置为初始值
		itemReduceEx = DROP_RAND_BASE_NUM;
		goldReduceEx = DROP_RAND_BASE_NUM;
	}
	return CreateDrop(nDropID, pScene, midPos, byDropType, setTypeVal, monsId, monsLev, dropInitProtect, source, itemReduceEx, goldReduceEx);
}

//移除掉落
bool DropMgr::RemoveDrop(uint64_t dropCid)
{
	Drop *pDrop = g_GetCreatureMgr()->GetDrop(dropCid);
	if (nullptr == pDrop)
	{
		return false;
	}
	if (pDrop->IsDestory()) //不能重复移除
	{
		return false;
	}
	//掉落移除
	return pDrop->Remove();
}

//安全区掉落  itemSubType : 物品子类型，配置表配置的
bool DropMgr::PlayerSafeAreaDrop(CharIDType charId, Point3<float>&pos, int32_t itemSubType, SDropSourcePram &source)
{
	Player *pPlayer = g_GetCreatureMgr()->GetNoScenePlayer(charId);
	if (nullptr == pPlayer)
	{
		return false;
	}
	Part *pPackage = pPlayer->GetPart(PART_PACKAGE);
	if (nullptr == pPackage)
	{
		return false;
	}
	const CItemBase *pItem = pPackage->GetItemByType(itemSubType);
	if (nullptr != pItem)
	{
		VEC_COMMON_ITEM vecPackage;
		vecPackage.clear();
		vecPackage.push_back(pItem);
		MAP_UINT16_INT32 mapIdxNum;
		mapIdxNum.clear();
		SET_Drop setDrop;
		setDrop.clear();
		SET_UINT64 setTypeVal;
		setTypeVal.clear();
		PackageDrop(pPlayer, pos, vecPackage, setDrop, mapIdxNum, (int8_t)EDropType::EDropType_Public, setTypeVal,source, pPlayer->GetCid());
		if (setDrop.size() > 0)
		{
			SItemSourceParam sourceParam;
			sourceParam.source = S_Drop;
			pPackage->RemoveAllByType(itemSubType, sourceParam);
			return true;
		}
	}
	return false;
}

//玩家下线掉落  itemSubType : 物品子类型，配置表配置的
bool DropMgr::PlayerLogoutDrop(CharIDType charId, int32_t itemSubType, SDropSourcePram &source)
{
	Player *pPlayer = g_GetCreatureMgr()->GetNoScenePlayer(charId);
	if (nullptr == pPlayer)
	{
		return false;
	}
	Part *pPackage = pPlayer->GetPart(PART_PACKAGE);
	if (nullptr == pPackage)
	{
		return false;
	}
	const CItemBase *pItem = pPackage->GetItemByType(itemSubType);
	if (nullptr != pItem)
	{
		VEC_COMMON_ITEM vecPackage;
		vecPackage.clear();
		vecPackage.push_back(pItem);
		MAP_UINT16_INT32 mapIdxNum;
		mapIdxNum.clear();
		SET_Drop setDrop;
		setDrop.clear();
		SET_UINT64 setTypeVal;
		setTypeVal.clear();
		PackageDrop(pPlayer, pPlayer->GetPos(), vecPackage, setDrop, mapIdxNum, (int8_t)EDropType::EDropType_Public, setTypeVal,source, pPlayer->GetCid());
		if (setDrop.size() > 0)
		{
			SItemSourceParam sourceParam;
			sourceParam.source = S_Drop;
			pPackage->RemoveAllByType(itemSubType, sourceParam);
			return true;
		}
	}
	return false;
}


//背包掉落
void DropMgr::PackageDrop(Player *pPlayer, Point3<float> pos, VEC_COMMON_ITEM &vecPackageItem, SET_Drop &setDrop, MAP_UINT16_INT32 &mapIdxNum, int8_t dropType, SET_UINT64 &setTypeVal, SDropSourcePram &source, CharIDType fromWho)
{
	if (nullptr == pPlayer)
	{
		return;
	}
	CharIDType charId = pPlayer->GetCid();
	VEC_COMMON_ITEM::iterator iter = vecPackageItem.begin();
	for (; iter != vecPackageItem.end(); ++iter)
	{
		const CItemBase *pPackageItem = (*iter);
		if (nullptr == pPackageItem)
		{
			continue;
		}
		int32_t byType = EItemType_common;
		uint32_t itemId = pPackageItem->GetItemID();
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(itemId);
		if (nullptr == pItemCfg)
		{
			const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(itemId);
			if (nullptr == pEquipCfg)
			{
				LogErrFmtPrint("[logic] DropMgr::PackageDrop...nullptr == pEquipCfg...cid:%lu, itemid:%u, dropType:%d,fromwho:%lu ", charId, itemId, dropType, fromWho);
				continue;
			}
			byType = EItemType_equip;
		}
		else
		{
			byType = EItemType_common;
		}
		CItemBase *pNewItem = g_GetItemMgr()->MakeItemObj(byType);
		if (nullptr != pNewItem)
		{
			if (pNewItem->CopyFrom(pPackageItem))
			{
				//掉落数量固定一个
				Drop *pDrop = g_GetCreatureMgr()->CreateDropEx(pNewItem, 0, pPlayer->GetSceneId(), pos, dropType, setTypeVal, DROP_INIT_PROTECT_TIME, source, fromWho);
				if (nullptr == pDrop)
				{
					g_GetItemMgr()->FreeItemObj(pNewItem);
					LogErrFmtPrint("[logic] DropMgr::PackageDrop...g_GetCreatureMgr()->CreateDrop failed...cid:%lu, itemid:%u, dropType:%d,fromwho:%lu ", charId, itemId,dropType,fromWho);
				}
				else
				{
					//掉落成功，才移除玩家背包物品，避免掉落不成功，玩家背包物品又被移除了
					setDrop.insert(pDrop);
					mapIdxNum[pPackageItem->GetIndex()] = pPackageItem->GetNum();
				}
			}
			else
			{
				g_GetItemMgr()->FreeItemObj(pNewItem);
				LogErrFmtPrint("[logic] DropMgr::PackageDrop...pNewItem->CopyFrom(pPackageItem) failed...cid:%lu, itemid:%u, dropType:%d,fromwho:%lu ", charId, itemId, dropType, fromWho);
			}
		} // end of if (nullptr != pNewItem)
		else
		{
			LogErrFmtPrint("[logic] DropMgr::PackageDrop...nullptr == pNewItem...cid:%lu, itemid:%u, dropType:%d,fromwho:%lu ", charId, itemId, dropType, fromWho);
		}
	}
}

//计算死亡经验
void DropMgr::OnCreatureDieExp(Creature * pCreature)
{
	if (!pCreature)
	{
		return;
	}
	Monster * pMonster = dynamic_cast<Monster*>(pCreature);
	if (!pMonster)
	{
		return;
	}

	const MonsterMonsterCfgInfo *pMonsCfg = pMonster->GetMonsterInfo();
	if (!pMonsCfg)
	{
		return;
	}

	//找到该怪物的仇恨列表
	//过率掉不在怪物60米范围的玩家
	//找出仇恨列表中的玩家所杀怪物血量百分比
	//找出组队玩家
	if (pMonster->GetAiData() == nullptr)
	{
		return;
	}

	int32_t monstExp =0;


	std::vector<int32_t> outParam;
	string str = pMonsCfg->exp;
	CommonApi::StrReplace(str, "<", "");
	CommonApi::StrReplace(str, ">", "");
	CommonApi::SplitStrToVecInt(str, ",", &outParam);
	if (outParam.size()==1)
	{
		monstExp = outParam[0];
	}
	else
	{
		if (outParam.size()!=5)
		{
			LogErrFmtPrint("calc monst exp error param!=5 monsteid=%d", pMonsCfg->monsterID);
			return;
		}
		uint32_t level = pCreature->GetAttr(C_LEVEL);
		monstExp = (pow(level, outParam[0]/10000.0)*outParam[1]/10000.0 + level*outParam[2]/10000.0 + outParam[3]/10000.0)*outParam[4]/10000.0;
	}
	
	

	auto & tmpList = pMonster->GetAiData()->GetHateList().GetHateList();
	std::list<HateTargetData>::iterator iter = tmpList.begin();
	std::map<uint32_t,std::vector<uint64_t> >  playerTeamList;
	std::vector<uint64_t>  playerList;
	std::map<uint32_t,uint64_t> vTeamDamage;
	playerList = pMonster->GetMonsterKillerList(&playerTeamList);
	for (; iter != tmpList.end();++iter)
	{
		Player * pPlayer = g_GetCreatureMgr()->GetPlayer(iter->m_hateTargetCid);
		
		if (!pPlayer)
		{
			continue;
		}

		uint32_t teamid = pPlayer->GetAttr(C_TEAM_ID);
		if (teamid <= 0)
		{
			//直接给经验
			if (pMonster->GetAttr(C_MAX_HP) > 0)
			{
				uint32_t exp = (iter->m_damageValue / (pMonster->GetAttr(C_MAX_HP)*1.0)) * monstExp;

				exp = OnReduceCreatureDieExp(pPlayer, pMonster, exp);
				pPlayer->AddExp(exp,exp,0);
			}
			else
			{
				LogErrFmtPrint("[logic] monster maxhp is zero...monsterid:%u, maxhp:%d ", pMonster->GetConfigId(), pMonster->GetAttr(C_MAX_HP));
			}
			
		}
		else
		{


			vTeamDamage[teamid] += iter->m_damageValue;
		}
	}

	//再给队伍发经验
	std::map<uint32_t, std::vector<uint64_t> >::iterator iterNewTeam = playerTeamList.begin();
	for (; iterNewTeam != playerTeamList.end(); ++iterNewTeam)
	{
		std::vector<uint64_t> vPlayer = iterNewTeam->second;

		for (std::vector<uint64_t>::iterator iterTeamPlayer = vPlayer.begin(); iterTeamPlayer != vPlayer.end(); ++iterTeamPlayer)
		{
			uint32_t exp = (vTeamDamage[iterNewTeam->first] * monstExp *(1 + (vPlayer.size() - 1)*0.1)*1.0) / (pMonster->GetAttr(C_MAX_HP)*vPlayer.size());
			Player * pPlayer = g_GetCreatureMgr()->GetPlayer(*iterTeamPlayer);
			if (pPlayer)
			{
				uint32_t percent = 0;
				int64_t closeLevel = pPlayer->GetPAttrValue(P_CLOSENESS_LEVEL);
				if (closeLevel>0)
				{
					percent = g_GetGTeamMgr()->GetTeamExpAdd(closeLevel);
					exp = exp*(1 + percent / 100.0f);
					LogDebugFmtPrint("closeness add exp percent=%d", percent);
				}
				exp = OnReduceCreatureDieExp(pPlayer, pMonster, exp);
				uint32_t baseExp = (vTeamDamage[iterNewTeam->first] * monstExp *1.0) / (pMonster->GetAttr(C_MAX_HP)*vPlayer.size());
				baseExp = OnReduceCreatureDieExp(pPlayer, pMonster, baseExp);
				pPlayer->AddExp(exp, baseExp,exp-baseExp);
			}
		}
	}

}

//通知衰减后得经验
int32_t DropMgr::OnReduceCreatureDieExp(Player * pPlayer, Monster * pCreature, int32_t exp)
{
	int32_t result = 0;
	if (!pPlayer || !pCreature)
	{
		return result;
	}


	//如果该怪物不需处理经验衰减，则直接返回原有经验 
	const MonsterMonsterCfgInfo* pConfig = pCreature->GetMonsterInfo();
	if (pConfig)
	{
		if (!pConfig->isLvDecay) //0表示不衰减
		{
			return exp;
		}
	}

	//先计算两个人的等级差
	int32_t level = pPlayer->GetAttr(C_LEVEL) - pCreature->GetAttr(C_LEVEL);


	const ReduceReduceCfgMap * pMap = g_GetReduceReduceCfgTable()->GetReduceReduceCfgMap();
	if (pMap && pMap->size()>0 )
	{

		{
			ReduceReduceCfgMap::const_iterator iter = pMap->find(level);
			if (iter != pMap->end())
			{
				result = (exp*iter->second.ExpReduce*1.0) / 10000.0;
			}
			else
			{
				if (level<=0)
				{
					result = exp;
				}
				else
				{
					result = 0;
				}
			}
		}
	}

	return result;
}

//传送区域附近找有效坐标
void DropMgr::FindPointLstInTelp(Player *p, Point3<float> &pos)
{
	if (nullptr == p)				return;
	Scene *pScene = p->GetScene();
	if (nullptr == pScene)			return;
	const VecTeleporterPosCfg* pVecPos = g_GetMapCfgMgr()->GetTelCfgByMap(p->GetMapId());
	if (nullptr == pVecPos)			return;
	for (VecTeleporterPosCfg::const_iterator iter = pVecPos->begin(); iter != pVecPos->end(); ++iter)
	{
		STeleporterPosCfgInfo telPos = *iter;
		if (pScene->InCircle(pos, telPos.telpos, 4))
		{
			VecPoint3 vecPos;
			pScene->FindPointLstInRect(pos, vecPos, 8.0f, 8.0f, 1);
			if (vecPos.size() < 1)	return;
			pos = vecPos.at(0);
			break;
		}
	}
}

//玩家死亡活动掉落
void DropMgr::PlayerDieDropByAct(Player *pDiePlayer, MAP_UINT32_INT32 &mapDropItem, SDropSourcePram &source, CharIDType killerId)
{
	if (nullptr == pDiePlayer)
	{
		return;
	}
	Part *pPackage = pDiePlayer->GetPart(PART_PACKAGE);
	if (nullptr == pPackage)
	{
		return;
	}
	const CItemBase *pItem = pPackage->GetItemByType((int32_t)EItemSubType::EItemSubType_special_kill_stone);
	if (nullptr != pItem)
	{
		VEC_COMMON_ITEM vecPackageItem;
		vecPackageItem.clear();
		vecPackageItem.push_back(pItem);
		MAP_UINT16_INT32 mapIdxNum;
		mapIdxNum.clear();
		SET_Drop setDrop;
		setDrop.clear();
		SET_UINT64 setTypeVal;
		setTypeVal.clear();
		
		Point3<float> &pos = pDiePlayer->GetPos();
		FindPointLstInTelp(pDiePlayer, pos);

		PackageDrop(pDiePlayer, pos, vecPackageItem, setDrop, mapIdxNum, (int8_t)EDropType::EDropType_Public, setTypeVal, source,pDiePlayer->GetCid());
		if (setDrop.size() > 0)
		{
			MAP_UINT16_INT32::iterator iterDel = mapIdxNum.begin();
			for (; iterDel != mapIdxNum.end(); ++iterDel)
			{
				const CItemBase *pItemBase = pPackage->GetItem(iterDel->first);
				if (nullptr != pItemBase)
				{
					MAP_UINT32_INT32::iterator iterDrop = mapDropItem.find(pItemBase->GetItemID());
					if (iterDrop != mapDropItem.end())
					{
						iterDrop->second += iterDel->second;
					}
					else
					{
						mapDropItem[pItemBase->GetItemID()] = iterDel->second;
					}
				}
			}
			//掉落成功，才移除玩家背包物品，避免掉落不成功，玩家背包物品又被移除了
			SItemSourceParam sourceParam;
			sourceParam.source = S_Drop;
			pPackage->RemoveAllByType((int32_t)EItemSubType::EItemSubType_special_kill_stone, sourceParam);
		}
	}
	pItem = pPackage->GetItemByType((int32_t)EItemSubType::EItemSubType_special_remains_god);
	if (nullptr != pItem)
	{
		VEC_COMMON_ITEM vecPackageItem;
		vecPackageItem.clear();
		vecPackageItem.push_back(pItem);
		MAP_UINT16_INT32 mapIdxNum;
		mapIdxNum.clear();
		SET_Drop setDrop;
		setDrop.clear();
		SET_UINT64 setTypeVal;
		setTypeVal.clear();

		Point3<float> &pos = pDiePlayer->GetPos();
		FindPointLstInTelp(pDiePlayer, pos);

		PackageDrop(pDiePlayer, pos, vecPackageItem, setDrop, mapIdxNum, (int8_t)EDropType::EDropType_Public, setTypeVal, source,pDiePlayer->GetCid());
		if (setDrop.size() > 0)
		{
			MAP_UINT16_INT32::iterator iterDel = mapIdxNum.begin();
			for (; iterDel != mapIdxNum.end(); ++iterDel)
			{
				const CItemBase *pItemBase = pPackage->GetItem(iterDel->first);
				if (nullptr != pItemBase)
				{
					MAP_UINT32_INT32::iterator iterDrop = mapDropItem.find(pItemBase->GetItemID());
					if (iterDrop != mapDropItem.end())
					{
						iterDrop->second += iterDel->second;
					}
					else
					{
						mapDropItem[pItemBase->GetItemID()] = iterDel->second;
					}
				}
			}

			//掉落成功，才移除玩家背包物品，避免掉落不成功，玩家背包物品又被移除了
			SItemSourceParam sourceParam;
			sourceParam.source = S_Drop;
			pPackage->RemoveAllByType((int32_t)EItemSubType::EItemSubType_special_remains_god, sourceParam);
			//玩家在陨落诅咒过程中死亡，则飘字信息提示：你被XXX玩家击杀，“神之遗骸”已遗失。
			if (killerId > 0)
			{
				SystemChatMsgData notify;
				notify.params.push_back(killerId);
				std::vector<CharIDType> iList;
				iList.push_back(pDiePlayer->GetCid());
				g_GetChatMgr()->SendBroadcastChat(BT_ACTIVITY_SON_OF_KILLING_FLOATING_F, notify, iList);
			}
		}
	}
}

void DropMgr::PlayerDieCommonDrop(Player *pDiePlayer, int8_t byType, int32_t dropNum, MAP_UINT32_INT32 &mapDropItem, SDropSourcePram &source)
{
	if (nullptr == pDiePlayer || dropNum <= 0)
	{
		return;
	}
	Part *pPackage = pDiePlayer->GetPart(PART_PACKAGE);
	if (nullptr == pPackage)
	{
		return;
	}
	CharIDType dieCid = pDiePlayer->GetCid();
	if (EDropFromType_Equip == byType)
	{
		VEC_COMMON_ITEM vecEquips;
		pPackage->GetAllCanDropEquip(vecEquips);
		int32_t equipSize = vecEquips.size();
		if (equipSize <= 0)
		{
			return;
		}
		SET_Drop setDrop;
		setDrop.clear();
		MAP_UINT16_INT32 mapIdxNum;
		mapIdxNum.clear();
		VEC_COMMON_ITEM vecDropItem;
		vecDropItem.clear();
		for (int32_t i = 0; i < dropNum; ++i)
		{
			if (equipSize > 0)
			{
				int32_t idx = Random(equipSize); // 0 - (equipSize - 1)
				if (idx < equipSize)
				{
					vecDropItem.push_back(vecEquips.at(idx));
					vecEquips.erase(vecEquips.begin() + idx);
					equipSize -= 1;
				}
			}
		}
		SET_UINT64 setTypeVal;
		setTypeVal.clear();
		PackageDrop(pDiePlayer, pDiePlayer->GetPos(), vecDropItem, setDrop, mapIdxNum, (int8_t)EDropType::EDropType_Public, setTypeVal, source, dieCid);
		if (mapIdxNum.size() > 0)
		{
			MAP_UINT16_INT32::iterator iterDel = mapIdxNum.begin();
			for (; iterDel != mapIdxNum.end(); ++iterDel)
			{
				const CItemBase *pItemBase = pPackage->GetItem(iterDel->first);
				if (nullptr != pItemBase)
				{
					MAP_UINT32_INT32::iterator iterDrop = mapDropItem.find(pItemBase->GetItemID());
					if (iterDrop != mapDropItem.end())
					{
						iterDrop->second += iterDel->second;
					}
					else
					{
						mapDropItem[pItemBase->GetItemID()] = iterDel->second;
					}
				}
			}


			SET_UINT8 setDelIdx;
			setDelIdx.clear();
			MAP_UINT16_INT32::iterator iterIdx = mapIdxNum.begin();
			for (; iterIdx != mapIdxNum.end(); ++iterIdx)
			{
				setDelIdx.insert(iterIdx->first);
			}
			pPackage->RemovePlayerEquip(setDelIdx);
		}
	}
	else if (EDropFromType_Package == byType)
	{
		VEC_COMMON_ITEM vecPackages;
		pPackage->GetAllCanDropPackage(vecPackages);
		int32_t packageSize = vecPackages.size();
		if (packageSize <= 0)
		{
			return;
		}
		MAP_UINT16_INT32 mapIdxNum;
		mapIdxNum.clear();
		SET_Drop setDrop;
		setDrop.clear();
		VEC_COMMON_ITEM vecDropItem;
		vecDropItem.clear();
		for (int32_t i = 0; i < dropNum; ++i)
		{
			if (packageSize > 0)
			{
				int32_t idx = Random(packageSize);
				if (idx < packageSize)
				{
					vecDropItem.push_back(vecPackages.at(idx));
					vecPackages.erase(vecPackages.begin() + idx);
					packageSize -= 1;
				}
			}
		}
		SET_UINT64 setTypeVal;
		setTypeVal.clear();
		PackageDrop(pDiePlayer, pDiePlayer->GetPos(), vecDropItem, setDrop, mapIdxNum, (int8_t)EDropType::EDropType_Public, setTypeVal, source,dieCid);
		if (mapIdxNum.size() > 0)
		{
			MAP_UINT16_INT32::iterator iterDel = mapIdxNum.begin();
			for (; iterDel != mapIdxNum.end(); ++iterDel)
			{
				const CItemBase *pItemBase = pPackage->GetItem(iterDel->first);
				if (nullptr != pItemBase)
				{
					MAP_UINT32_INT32::iterator iterDrop = mapDropItem.find(pItemBase->GetItemID());
					if (iterDrop != mapDropItem.end())
					{
						iterDrop->second += iterDel->second;
					}
					else
					{
						mapDropItem[pItemBase->GetItemID()] = iterDel->second;
					}
				}
			}
			SItemSourceParam soureParam;
			soureParam.source = S_Drop;
			pPackage->RemoveItem(mapIdxNum, soureParam);
		}
	}
}


//玩家死亡掉落
void DropMgr::OnPlayerDieDrop(Player *pDiePlayer, CharIDType killerCid, MAP_UINT32_INT32 &mapDropItem, bool &removeItemFalg, SDropSourcePram &source)
{
	if (nullptr == pDiePlayer)
	{
		return;
	}
	uint32_t sceneId = pDiePlayer->GetSceneId();
	Scene* pScene = g_GetSceneMgr()->GetScene(sceneId);
	if (pScene == nullptr)
	{
		return;
	}
	uint32_t mapId = pScene->GetMapId();
	const MapMapCfgInfo *pMapInfo = g_GetMapMapCfgTable()->GetMapMapCfgInfo(mapId);
	if (pMapInfo == nullptr)
	{
		return;
	}
	if (!pMapInfo->deadPunish) //地图不允许玩家死亡掉落
	{
		return;
	}
	
	//这里处理玩家死亡(自杀，PVE,PVP) 活动相关的掉落
	PlayerDieDropByAct(pDiePlayer,mapDropItem,source, killerCid);
	if (killerCid == pDiePlayer->GetCid()) //自杀不掉落
	{
		return;
	}	
	PackagePart *pDiePackagePart = dynamic_cast<PackagePart*>(pDiePlayer->GetPart(PART_PACKAGE));
	if (nullptr == pDiePackagePart)
	{
		return;
	}
	
	/*
	玩家在副本内死亡时，不掉落任何物品。
	遗失之城争夺战的活动期间内，整个诺林之心地图玩家死亡后不会掉落任何物品
	*/
	if (pDiePlayer->GetAttr(C_DUPLICATE_ID) > 0
		|| !g_GetGActivityMgr()->CanDeadDrop(pDiePlayer)
		)
	{
		return;
	}

	/*
	玩家死亡时，如果当前背包中有道具“替身娃娃”，
	1.扣除拥有的替身娃娃道具数量1个
	2.不再走PK物品掉落规则（即不掉落物品）
	*/
	const ConstantConstantCfgInfo *pConstCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_PkNoDropItem);
	if (nullptr != pConstCfg)
	{
		uint32_t itemId = pConstCfg->constantdata;
		SItemSourceParam sourceParam;
		sourceParam.source = S_DeathDrop;
		if (pDiePackagePart->RemoveItem(itemId, 1, sourceParam))
		{
			//扣除成功，不用走PK掉落规则，直接返回
			removeItemFalg = true;
			return;
		}
	}

	//死亡玩家杀戮值
	int32_t dieKillValue = 0;
	int32_t killerLev = 0;
	int32_t dropAtkType = -1;//死亡掉落攻击者类型
	PvpPart *pDiePvpPart = dynamic_cast<PvpPart*>(pDiePlayer->GetPart(PART_PVP));
	if (nullptr != pDiePvpPart)
	{
		dieKillValue = pDiePvpPart->GetPkKillingValue();
	}

	Creature *pKiller = pScene->GetCreature(killerCid);
	if (nullptr == pKiller)
	{
		return;
	}
	//击杀这等级
	killerLev = pKiller->GetAttr(C_LEVEL);
	if (CREATURE_PLAYER == pKiller->CreatureKind()) //玩家
	{
		dropAtkType = EDropAtkType_Player;
	}
	else if (CREATURE_MONSTER == pKiller->CreatureKind()) //怪物
	{
		dropAtkType = EDropAtkType_Monster;
	}
	

	//等级差
	int32_t lev = killerLev - pDiePlayer->GetAttr(C_LEVEL);
	//总的基础掉落概率
	int32_t totalBase = 0;
	//获取等级差对应的死亡概率值
	const PkmodeDeathPenaltyCfgInfo *pPkDeathCfgInfo = g_GetPkModeCfgMgr()->GetPkDeatchCfgInfo(dropAtkType, lev);
	if (nullptr == pPkDeathCfgInfo)
	{
		return;
	}
	totalBase += pPkDeathCfgInfo->baseDropProb;

	//获取杀戮值对应的基础掉落概率加成	
	int32_t dropCoef = 0;
	const PkmodePkWantedCfgInfo *pPkWantedCfgInfo = g_GetPkModeCfgMgr()->GetPkWantedCfgInfo(dieKillValue);
	if (nullptr != pPkWantedCfgInfo)
	{
		dropCoef = pPkWantedCfgInfo->baseDropPlus * dieKillValue;
		if (dropCoef > pPkWantedCfgInfo->baseMax)
		{
			dropCoef = pPkWantedCfgInfo->baseMax;
		}
	}	
	totalBase += dropCoef;
	
	if (totalBase <= 0)
	{
		return;
	}
	//随机是否掉落
	int32_t rndNum = Random(DROP_RAND_BASE_NUM);
	if (rndNum > totalBase)
	{
		return;
	}

	//掉背包还是掉身上的装备
	int8_t byDropFrom = 0;
	int32_t rndNumA = Random(DROP_RAND_BASE_NUM);
	if (rndNumA <= pPkDeathCfgInfo->bagDropProb) //掉背包
	{
		byDropFrom = EDropFromType_Package;
	}
	else if(rndNumA < pPkDeathCfgInfo->equipDropProb) //掉装备
	{
		byDropFrom = EDropFromType_Equip;
	}
	else
	{
		return;
	}

	//被怪物击杀，只掉背包物品
	if (EDropAtkType_Monster == dropAtkType && EDropFromType_Package != byDropFrom)
	{
		return;
	}
	
	//随机掉落数量
	int32_t dropNum = 1;//默认数量为1
	if (EDropFromType_Package == byDropFrom) //背包可以掉落多组，身上的装备只会掉一件
	{
		int32_t rndNumB = Random(DROP_RAND_BASE_NUM);		
		VEC_INT32::const_iterator iterProb = pPkDeathCfgInfo->vec_prob.begin();
		for (; iterProb != pPkDeathCfgInfo->vec_prob.end(); ++iterProb)
		{
			int32_t prob = (*iterProb);
			if (rndNumB < prob)
			{
				break;
			}
			++dropNum;
		}
	}	
	if (dropNum <= 0)
	{
		return;
	}

	PlayerDieCommonDrop(pDiePlayer, byDropFrom, dropNum,mapDropItem,source);
}
//怪物HP掉落
bool DropMgr::OnMonsHpDrop(uint32_t sceneId, uint32_t dropId, Point3<float> pos, uint32_t monsId, int32_t monsLev, SDropSourcePram &source)
{
	Scene *pScene = g_GetSceneMgr()->GetScene(sceneId);
	if (nullptr == pScene)
	{
		return false;
	}
	SET_UINT64 setTypeVal;
	setTypeVal.clear();
	int32_t openReduce = 0;
	int32_t dropInitProtect = 0;
	GetMonsDropParam(monsId, openReduce, dropInitProtect);
	return AddDrop(nullptr, pScene, dropId, pos, (int8_t)EDropType::EDropType_Public, setTypeVal, monsId, monsLev, dropInitProtect, openReduce, source);
}

//获取玩家box条件
void DropMgr::GetBoxCond(CharIDType cid, BoxCondCfg &boxCond)
{
	GetBoxCond(g_GetCreatureMgr()->GetPlayer(cid), boxCond);
}
//获取玩家box条件
void DropMgr::GetBoxCond(Player *pPlayer, BoxCondCfg &boxCond)
{
	if (nullptr == pPlayer)
	{
		return;
	}
	boxCond.byProf = pPlayer->GetAttr(C_PROF);
	boxCond.bySex = pPlayer->GetAttr(C_GENDER);
	boxCond.nLevel = pPlayer->GetAttr(C_LEVEL);
	boxCond.camp = pPlayer->GetAttr(C_CAMP_ID);
}


//获取玩家物品条件
void DropMgr::GetItemCond(CharIDType cid, SItemCond &itemCond, EItemInitAttrType initType /*= EItemInitAttrType_Common*/)
{
	GetItemCond(g_GetCreatureMgr()->GetPlayer(cid), itemCond, initType);
}

void DropMgr::GetItemCond(Player *pPlayer, SItemCond &itemCond, EItemInitAttrType initType /*= EItemInitAttrType_Common*/)
{
	if (nullptr == pPlayer)
	{
		return;
	}
	itemCond.inittype = initType;
	itemCond.level = pPlayer->GetAttr(C_LEVEL);
	itemCond.camp = pPlayer->GetAttr(C_CAMP_ID);
}

//怪物死亡掉落
void DropMgr::OnMonsterDieDrop(DieEvent *pDieEvent)
{
	if (nullptr == pDieEvent)
	{
		return;
	}
	if (pDieEvent->monsterId <= 0)
	{
		return;
	}
	const MonsterMonsterCfgInfo *pMonsCfg = g_GetMonsterMonsterCfgTable()->GetMonsterMonsterCfgInfo(pDieEvent->monsterId);
	if (nullptr == pMonsCfg)
	{
		return;
	}
	Scene *pScene = g_GetSceneMgr()->GetScene(pDieEvent->sceneId);
	if (nullptr == pScene)
	{
		return;
	}
	Point3<float> midPos;
	int32_t monsLev = pMonsCfg->monsterLV;
	uint32_t monsId = pDieEvent->monsterId;
	Monster* pMonsCreature = pScene->GetMonster(pDieEvent->nCid);
	if (nullptr != pMonsCreature)
	{
		midPos = pMonsCreature->GetPos();
		monsLev = pMonsCreature->GetAttr(C_LEVEL);
	}

	//怪物死亡经验加成
	Creature* pCreature = pScene->GetCreature(pDieEvent->killerCid);
	if (pCreature)
	{
		Player *pPlayer = dynamic_cast<Player*>(pCreature);
		if (nullptr != pPlayer)
		{
			BEGIN_PROFILE("DropMgr::OnCreatureDieExp");
			OnCreatureDieExp(pMonsCreature);
			END_PROFILE();

			//任务专属掉落
			//OnMissionDrop(pPlayer, monsId, monsLev, midPos);
		}
		//考虑召唤物和宠物
	}

	BEGIN_PROFILE("DropMgr::give reword");

	IDuplicate *pDuplicate = g_GetDuplicateMgr()->GetDuplicate(pDieEvent->sceneId);
	if (nullptr != pDuplicate)
	{
		if (!pDuplicate->IsEnd())//副本没结束时才会有奖励
		{
			SDropSourcePram source;
			source.source = EDropSource_Dup;
			source.sourceVal = pDuplicate->GetDuplicateID();
			if ((int8_t)EDuplicateType::EDuplicateType_Cloud == pDuplicate->GetType()) //云端试炼副本掉落和 野外掉落一样
			{
				Creature* pDropOwnerCreature = pScene->GetCreature(pDieEvent->dropOwnerCid);
				//云端试练这里当作 活动来源
				source.source = EDropSource_Act;
				source.sourceVal = g_GetDuplicateCfgMgr()->GetCloudActId();
				AddNormalDrop(pDropOwnerCreature, pScene, pMonsCfg->dropDefault, pMonsCfg->dropType, midPos, monsId, monsLev, source);
			}
			else if ((int8_t)EDuplicateType::EDuplicateType_UnionHome == pDuplicate->GetType())
			{
				//工会驻地怪物掉落 放到相关活动那边,每个活动都有自己的掉落条件
			}
			else
			{
				const DuplicateDuplicateCfgInfo *pdupcfg = pDuplicate->GetDuplicateCfgInfo();
				//副本怪，副本怪都是独立掉落,怪物自身掉落 + 副本掉落
				const MAP_Player* pSceneAllPlayers = pScene->GetAllPlayerInScene();
				if (nullptr != pSceneAllPlayers)
				{
					MAP_Player::const_iterator iterPlayer = pSceneAllPlayers->begin();
					for (; iterPlayer != pSceneAllPlayers->end(); ++iterPlayer)
					{
						Player* pPlayer = iterPlayer->second;
						if (nullptr == pPlayer)
						{
							continue;
						}
						//怪物自身掉落
						if (pMonsCreature)
						{
							AddDrop(pPlayer, midPos, (uint32_t)pMonsCfg->dropDefault, monsId, monsLev, source);
						}
						//副本掉落
						if (nullptr != pdupcfg)
						{
							uint32_t dupDropId = 0;
							if (ENUM_MONSTER_TYPE_LITTLE_MONSTER == pMonsCfg->monsterType)
							{
								dupDropId = (uint32_t)pdupcfg->dropNormalMonster;
							}
							else if (ENUM_MONSTER_TYPE_BIG_MONSTER == pMonsCfg->monsterType)
							{
								dupDropId = (uint32_t)pdupcfg->dropEliteMonster;
							}

							if (pMonsCreature)
							{
								AddDrop(pPlayer, midPos, dupDropId, monsId, monsLev, source);
							}
						}

					}
				} // end of if (nullptr != pScenePlayers)
			}			
		} // end of if (!pDuplicate->IsEnd())	
	}
	else
	{		
		SDropSourcePram source;
		source.source = EDropSource_Map;
		source.sourceVal = pDieEvent->sceneId;
		//非副本怪
		if (EMonsCreateType_Activity == pDieEvent->createType)
		{
			source.source = EDropSource_Act;
			source.sourceVal = pDieEvent->createTypeVal;
		}
		else if (EMonsCreateType_Escort == pDieEvent->createType)
		{
			source.source = EDropSource_Act;
			source.sourceVal = g_GetDuplicateCfgMgr()->GetEscortActId();
		}

		//等级差
		int32_t diffLev = 0;
		int32_t itemReduce = DROP_RAND_BASE_NUM;
		int32_t goldReduce = DROP_RAND_BASE_NUM;
		if (nullptr != pCreature && nullptr != pMonsCreature)
		{
			diffLev = pCreature->GetAttr(C_LEVEL) - pMonsCreature->GetAttr(C_LEVEL);
			g_GetReduceCfgMgr()->GetReduceRate(diffLev, itemReduce, goldReduce);
		}
		
		Creature* pDropOwnerCreature = pScene->GetCreature(pDieEvent->dropOwnerCid);
		AddNormalDrop(pDropOwnerCreature, pScene, pMonsCfg->dropDefault, pMonsCfg->dropType, midPos, monsId, monsLev, source,itemReduce, goldReduce);

		//杀戮之子活动怪物 特殊掉落, 公共掉落
		if (pDieEvent->monsterId == g_GetGActivityMgr()->GetSonOfKillingMonsterId())
		{
			uint32_t extraDropId = g_GetGActivityMgr()->GetSonOfKillingExtraDropId();
			SET_UINT64 setTypeVal;
			setTypeVal.clear();
			int32_t openReduce = 0;
			int32_t dropInitProtect = 0;
			GetMonsDropParam(pMonsCfg, openReduce, dropInitProtect);
			source.source = EDropSource_Act;
			source.sourceVal = g_GetDuplicateCfgMgr()->GetSonOfKillingActId();
			AddDrop(nullptr, pScene, extraDropId, midPos, (int8_t)EDropType::EDropType_Public, setTypeVal, monsId, monsLev, dropInitProtect, openReduce, source);
		}
	}

	//任务杀怪处理
	OnMissionKillMons(*pDieEvent, monsLev, midPos);

	END_PROFILE();
}

//玩家添加宝箱物品
ERetCode DropMgr::PlayerAddBox(Player *pPlayer, VEC_INT32 &nBoxIdList, SItemSourceParam &souceParam)
{
	if (nullptr == pPlayer)
	{
		LogErrFmtPrint("[logic] DropMgr::PlayerAddBox...nullptr == pPlayer...fail");
		return RET_FAIL;
	}
	Part *pPackage = pPlayer->GetPart(PART_PACKAGE);
	if (nullptr == pPackage)
	{
		LogErrFmtPrint("[logic] DropMgr::PlayerAddBox...nullptr == pPackage...fail");
		return RET_FAIL;
	}
	VEC_ITEM_PROTO_EX vecItems;
	vecItems.clear();
	int32_t gold = 0;
	int32_t diamond = 0;
	int32_t binddiamond = 0;
	BoxCondCfg boxCond;
	GetBoxCond(pPlayer, boxCond);
	for (VEC_INT32::iterator iter = nBoxIdList.begin(); iter != nBoxIdList.end(); iter++)
	{
		if (!g_GetItemMgr()->CreateBoxDropItem((uint32_t)*iter, vecItems, gold, diamond, binddiamond, boxCond))
		{
			return RET_FAIL;
		}
	}
	if (!pPackage->AddItem(vecItems, souceParam))
	{
		return RET_PACKAGE_SPACE_NOT_ENOUGH;
	}
	if (gold > 0)
	{
		//pPlayer->AddAttr(C_GOLD, gold, true);
		pPlayer->AddSourceAttr(C_GOLD, gold, true, souceParam.source);
	}
	if (diamond > 0)
	{
		//pPlayer->AddAttr(C_DIAMOND_BIND, diamond, true);
		pPlayer->AddSourceAttr(C_DIAMOND, diamond, true, souceParam.source);
	}
	if (binddiamond > 0)
	{
		pPlayer->AddSourceAttr(C_DIAMOND_BIND, binddiamond, true, souceParam.source);
	}
	return RET_SUCCESS;
}

//使用物件掉落
void DropMgr::UseThingDrop(Player *pPlayer, uint32_t monsterId, int32_t monsLev,Point3<float> &pos)
{
	const MonsterMonsterCfgInfo *pMonsCfg = g_GetMonsterMonsterCfgTable()->GetMonsterMonsterCfgInfo(monsterId);
	if (nullptr == pMonsCfg)
	{
		return;
	}
	//使用物件掉落
	VEC_INT32 vecBox;
	vecBox.push_back(pMonsCfg->dropDefault);
	SItemSourceParam sourceParam;
	PlayerAddBox(pPlayer, vecBox, sourceParam);

	//使用物件 任务专属掉落
	OnMissionDrop(pPlayer, monsterId, monsLev,pos);
}

//任务杀怪
void DropMgr::OnMissionKillMons(DieEvent &dieEvent, int32_t monsLev, Point3<float> &pos)
{
	//统计仇恨列表和归属列表中组队的玩家
	SET_UINT64 setTarget;
	setTarget.clear();
	if (dieEvent.killerCid > 0)//先把击杀着加入到目标玩家列表中
	{
		setTarget.insert(dieEvent.killerCid);
	}
	//
	VEC_UINT64::iterator iterHate = dieEvent.hateTargetList.begin();
	for (; iterHate != dieEvent.hateTargetList.end(); ++iterHate)
	{
		setTarget.insert((*iterHate));
	}
	ORDER_MAP_UINT32_VEC_UINT64::iterator iterTeam = dieEvent.mapTargetTeamMem.begin();
	for (; iterTeam != dieEvent.mapTargetTeamMem.end(); ++iterTeam)
	{
		VEC_UINT64 &vecMem = iterTeam->second;
		VEC_UINT64::iterator iterMem = vecMem.begin();
		for (; iterMem != vecMem.end(); ++iterMem)
		{
			setTarget.insert((*iterMem));
		}

	}
	//任务杀怪计数
	SET_UINT64::iterator iterTarget = setTarget.begin();
	for (; iterTarget != setTarget.end(); ++iterTarget)
	{
		CharIDType shareCid = (*iterTarget);
		Player* pPlayer = g_GetCreatureMgr()->GetPlayer(shareCid);
		if (nullptr != pPlayer)
		{
			MissionPart* pMissionPart = dynamic_cast<MissionPart*>(pPlayer->GetPart(PART_MISSION));
			if (nullptr != pMissionPart)
			{
				pMissionPart->ShareKillMons(dieEvent.monsterId, dieEvent.killerCid, monsLev, dieEvent.count, pos);
			}
		}
	}
}
//任务掉落
void DropMgr::OnMissionDrop(Player *pPlayer, uint32_t monsterId,int32_t monsLev,Point3<float> &pos)
{
	//判断任务额外的掉落
	MissionPart* pMissionPart = dynamic_cast<MissionPart*>(pPlayer->GetPart(PART_MISSION));
	if (nullptr != pMissionPart)
	{
		pMissionPart->MissionDropByKillMons(monsterId, monsLev,pos);
	}
}

//动态怪掉落
void DropMgr::OnDyMonsDrop(uint32_t monsId, int32_t monsLev, VEC_ITEM_PROTO_EX &vecProtoEx, VEC_UINT32 &vecGold, SItemCond &itemCond, int32_t goldReduce, int32_t itemReduce)
{
	LuaScript *pScript = g_GetScriptMgr()->GetScript();
	if (nullptr == pScript)
	{
		LogErrFmtPrint("[logic] DropMgr::OnDyMonsDrop... nullptr == pScript, monsId:%u,monsLev:%d, goldReduce:%d, itemReduce:%d ", monsId, monsLev, goldReduce,itemReduce);
		return;
	}
	luabridge::LuaRef refRet(pScript->GetState());
	if (!pScript->CallTableFuncRet("Drop", "GetDynamicMonsDrop", refRet,monsId,monsLev,goldReduce,itemReduce))
	{
		LogErrFmtPrint("[logic] DropMgr::OnDyMonsDrop... pScript->CallTableFuncRet return false...monsId:%u,monsLev:%d, goldReduce:%d, itemReduce:%d ", monsId, monsLev, goldReduce, itemReduce);
		return;
	}
	if (refRet.isNil())
	{
		//LogErrFmtPrint("[logic] LogicActivityModule::LuaGetAncientElfCfg... refRet.isNil()...monsId:%u,monsLev:%d, goldReduce:%d, itemReduce:%d ", monsId, monsLev, goldReduce, itemReduce);
		return;
	}
	//金币
	luabridge::LuaRef refGold = refRet["gold"];
	if (refGold.isTable())
	{
		int32_t len = refGold.length();
		for (int32_t i = 1; i <= len; ++i)
		{
			int32_t gold = refGold[i].cast<int32_t>();
			if (gold > 0)
			{
				vecGold.push_back(gold);
				//LogDebugFmtPrint("DropMgr::OnDyMonsDrop...gold:%d, monsid:%u, monslev:%d,goldReduce:%d,itemReduce:%d ",gold,monsId,monsLev,goldReduce,itemReduce);
			}
		}
	}
	//物品
	LIST_ITEM lstItem;
	lstItem.clear();
	luabridge::LuaRef refItem = refRet["item"];
	if (refItem.isTable())
	{
		int32_t itemlen = refItem.length();
		for (int32_t j = 1; j <= itemlen; ++j)
		{
			luabridge::LuaRef refSingle = refItem[j];
			SItem item;
			item.nItemID = refSingle["item_id"].cast<uint32_t>();
			item.nNum = refSingle["item_num"].cast<int32_t>();
			lstItem.push_back(item);

			//LogDebugFmtPrint("DropMgr::OnDyMonsDrop...itemid:%u,num:%d, monsid:%u, monslev:%d,goldReduce:%d,itemReduce:%d ", item.nItemID,item.nNum, monsId, monsLev, goldReduce, itemReduce);
		}		
	}
	if (lstItem.size() > 0)
	{
		g_GetItemMgr()->CreateItem(lstItem, vecProtoEx,itemCond);
	}
}

//活动期间怪物掉落
void DropMgr::OnMonsDropDuringAct(uint32_t monsId, VEC_ITEM_PROTO_EX &vecProtoEx, VEC_UINT32 &vecGold, int32_t goldReduce, int32_t itemReduce)
{
	_UNUSE(goldReduce);
	_UNUSE(itemReduce);
	const MAP_UINT32_UINT32 *pMonsActDrop = g_GetDropCfgMgr()->GetMonsActDrop(monsId);
	if (nullptr == pMonsActDrop)
	{
		return;
	}
	MAP_UINT32_UINT32::const_iterator iterAct = pMonsActDrop->begin();
	for (; iterAct != pMonsActDrop->end(); ++iterAct)
	{
		uint32_t actid = iterAct->first;
		uint32_t dropid = iterAct->second;
		const OperateActConfigItem *pOperateCfg =  g_GetOperateWelfareMgr()->GetWelfareConfigItem(actid);
		if (nullptr != pOperateCfg && pOperateCfg->GetIsOpen())
		{
			//跟策划确认过，怪物活动期间的掉落没有衰减机制
			SItemCond itemCond; //掉落物品不知道物品条件，这里取默认值
			g_GetItemMgr()->CreateDropItem(dropid, vecProtoEx, vecGold, itemCond, DROP_RAND_BASE_NUM, DROP_RAND_BASE_NUM);
		}
	}
}

//获取怪物掉落参数
void DropMgr::GetMonsDropParam(uint32_t monsId, int32_t &openReduce, int32_t &dropInitProtect)
{
	const MonsterMonsterCfgInfo *pMonsCfg = g_GetMonsterMonsterCfgTable()->GetMonsterMonsterCfgInfo(monsId);
	GetMonsDropParam(pMonsCfg, openReduce, dropInitProtect);
}
//获取怪物掉落参数
void DropMgr::GetMonsDropParam(const MonsterMonsterCfgInfo *pMonsCfg, int32_t &openReduce, int32_t &dropInitProtect)
{
	//默认值
	openReduce = 1;
	dropInitProtect = DROP_INIT_PROTECT_TIME;
	if (nullptr == pMonsCfg)
	{
		return;
	}
	dropInitProtect = pMonsCfg->dropInitialTime;
	if (!pMonsCfg->isLvDecay)
	{
		openReduce = 0;
	}
}